﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.Streams;

namespace IRRemoteControl
{
    public class WavFile
    {
        public int Channels
        {
            get;
            set;
        }

        public int SampleRate
        {
            get;
            set;
        }

        public int BitsPerSample
        {
            get;
            set;
        }

        private List<byte> data = new List<byte>();

        public WavFile(int channels, int sampleRate, int bitsPerSample)
        {
            Channels = channels;
            SampleRate = sampleRate;
            BitsPerSample = bitsPerSample;
        }

        public void AppendData(params byte[] data)
        {
            this.data.AddRange(data);
        }

        public void AppendData(params short[] data)
        {
            foreach (var sample in data)
            {
                this.data.Add((byte)sample);
                this.data.Add((byte)(sample >> 8));
            }
        }

        public async Task<IRandomAccessStream> ToStream()
        {
            InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream();
            
            var writer = new BinaryWriter(stream.AsStreamForWrite());
            WriteTo(writer);
            writer.Flush();

            return stream;
        }

        public async Task<StorageFile> SaveAsync(StorageFolder folder, string filename)
        {
            var file = await folder.CreateFileAsync(filename);
            
            using (var stream = await file.OpenStreamForWriteAsync())
            {
                using (var writer = new BinaryWriter(stream))
                {
                    WriteTo(writer);
                }
            }

            return file;
        }

        private void WriteTo(BinaryWriter writer)
        {
            writer.Write(Encoding.UTF8.GetBytes("RIFF"));
            writer.Write(data.Count + 36);
            writer.Write(Encoding.UTF8.GetBytes("WAVE"));
            writer.Write(Encoding.UTF8.GetBytes("fmt "));
            writer.Write(16);
            writer.Write((short)1);
            writer.Write((short)Channels);

            writer.Write(SampleRate);

            var bytesPerSec = BitsPerSample / 8 * Channels * SampleRate;
            writer.Write(bytesPerSec);

            writer.Write((short)(BitsPerSample / 8 * Channels));
            writer.Write((short)BitsPerSample);

            writer.Write(Encoding.UTF8.GetBytes("data"));
            writer.Write(data.Count);
            writer.Write(data.ToArray());
        }
    }
}
